﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;

namespace PurpleKnife.Shell
{
    static class ConsoleExtensions
    {
        // Gets the standard handle.
        [DllImport("Kernel32.dll")]
        public static extern IntPtr GetStdHandle([MarshalAs(UnmanagedType.U4)] int nStdHandle);
        // Sets the console mode.
        [DllImport("Kernel32.dll")]
        public static extern bool SetConsoleMode(IntPtr hConsoleHandle, [MarshalAs(UnmanagedType.U4)] int dwMode);
        // Gets the console mode.
        [DllImport("Kernel32.dll")]
        public static extern bool GetConsoleMode(IntPtr hConsoleHandle, [Out,
        MarshalAs(UnmanagedType.U4)] out int dwMode);
        // Get STDIN handle
        public static int STD_INPUT_HANDLE = -10;
        // Get STDOUT handle
        public static int STD_OUTPUT_HANDLE = -11;
        // Enable/Disable WRAP_AT_EOL
        public static int ENABLE_WRAP_AT_EOL_OUTPUT = 0x0002;
        
        // find window handle
        [DllImport("user32.dll")]
        public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
        
        // show or hide window
        [DllImport("user32.dll")]
        static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
        // showwindow constants
        public static int SW_HIDE = 0;
        public static int SW_SHOWNORMAL = 1;
        
        // flash window declare
        [DllImport("user32.dll")]
        [return: MarshalAs(UnmanagedType.Bool)]
        static extern bool FlashWindowEx(ref FLASHWINFO pwfi);
        // flashwindow info struct
        [StructLayout(LayoutKind.Sequential)]
        public struct FLASHWINFO
        {
            public UInt32 cbSize;
            public IntPtr hwnd;
            public UInt32 dwFlags;
            public UInt32 uCount;
            public Int32 dwTimeout;
        }
        public const UInt32 FLASHW_ALL = 3;

        // member vars
        private static IntPtr hwnd = System.Diagnostics.Process.GetCurrentProcess().MainWindowHandle;
        private static bool _wrapAtEOL;
        private static bool _consoleVisible;


        // enable/disable WRAP_AT_EOL
        public static bool WrapAtEOL
        {
            // set WrapAtEOL mode
            set
            {
                // Get STDOUT handle
                IntPtr hOut = GetStdHandle(STD_OUTPUT_HANDLE);
                // Get the console mode
                int pintMode = 0;
                bool pblnResult = GetConsoleMode(hOut, out pintMode);                 
                if (value == true)
                {
                    pblnResult = SetConsoleMode(hOut, pintMode & ~ENABLE_WRAP_AT_EOL_OUTPUT);
                }
                else
                {
                    pblnResult = SetConsoleMode(hOut, pintMode & ~ENABLE_WRAP_AT_EOL_OUTPUT); 
                }
                _wrapAtEOL = value;
            }

            // get WrapAtEOL mode
            get { return _wrapAtEOL; }
        }

        // console visibility
        public static bool Visible
        {
            set
            {
                // obtain window handle
                
                
                if (value)
                {
                    // show
                    ShowWindow(hwnd, SW_SHOWNORMAL);
                }
                else
                {
                    // hide
                    ShowWindow(hwnd, SW_HIDE);
                }
                _consoleVisible = value;
            }

            get
            {
                return _consoleVisible;
            }

        }

        public static void FlashWindow(uint Count)
        {
            FLASHWINFO fInfo = new FLASHWINFO();

            fInfo.cbSize = Convert.ToUInt32(Marshal.SizeOf(fInfo));
            fInfo.hwnd = hwnd;
            fInfo.dwFlags = FLASHW_ALL;
            if (Count == 0) { fInfo.uCount = UInt32.MaxValue; } else { fInfo.uCount = Count; }
            fInfo.dwTimeout = 0;

            FlashWindowEx(ref fInfo);
        }
    }
}
